home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH10 / EX10_1.ASM < prev    next >
Encoding:
Assembly Source File  |  1996-02-08  |  4.2 KB  |  277 lines

  1. ; Ex10_1.asm
  2. ;
  3. ; Software that plays Musical notes.
  4. ; Intended for use with Chapter 10 Laboratory Experiments
  5.  
  6.  
  7.         .xlist
  8.         include     stdlib.a
  9.         includelib    stdlib.lib
  10.         .list
  11.  
  12. ; Hardware related equates
  13.  
  14. PPI_B        equ    61h        ;8255 port B address
  15. PIT_Ch2        equ    42h        ;Timer channel 2 address
  16. PIT_CW        equ    43h        ;Timer control word address.
  17.  
  18. RTC        textequ    <es:[6ch]>    ;Real Time clock writes here.
  19.  
  20.  
  21.  
  22.  
  23.  
  24. ; The following macros program the 8254 timer chip to play a
  25. ; note or a rest.
  26.  
  27. Note        macro    frequency, duration
  28.         mov    ax, frequency
  29.         mov    cx, duration
  30.         call    PlayNote
  31.         endm
  32.  
  33. Rest        macro    Duration
  34.         local    RestLoop
  35.  
  36. ;; Turn off the speaker.
  37.  
  38.         in    al, PPI_B
  39.         and    al, 0FCh
  40.         out    PPI_B, al
  41.  
  42.         mov    cx, Duration
  43. RestLoop:    call    Delay18
  44.         loop    RestLoop
  45.         endm
  46.  
  47.  
  48.  
  49.  
  50. dseg        segment    para public 'data'
  51.  
  52. ; See Delay18.asm for details about the following variables.
  53.  
  54. TimedValue    word    0
  55. RTC2        word    0
  56.  
  57.  
  58. ; DivisorConst is the constant that, when divided by a desired frequency
  59. ; produces the divisor constant to feed into the timer chip to produce
  60. ; a tone of the given frequency.
  61.  
  62. DivisorConst    dword    1193180
  63.  
  64.  
  65. dseg        ends
  66.  
  67. ;********************************************************
  68.  
  69.  
  70.  
  71.  
  72.  
  73. cseg        segment    para public 'code'
  74.         assume    cs:cseg, ds:dseg
  75.  
  76. ; Delay- This routine delays for approximately 1/18th second.
  77. ;      See the Delay18.asm file for comments about this code.
  78.  
  79. Delay18        proc    near
  80.         push    ds
  81.         push    es
  82.         push    ax
  83.         push    bx
  84.         push    cx
  85.         push    dx
  86.         push    si
  87.  
  88.         mov    ax, dseg
  89.         mov    es, ax
  90.         mov    ds, ax
  91.         mov    cx, TimedValue
  92.         mov    si, es:RTC2
  93.         mov    dx, PPI_B
  94.  
  95.         align    4
  96. TimeRTC:    mov    bx, 50
  97.         align    4
  98. DelayLp:    dec    bx
  99.         jne    DelayLp
  100.         cmp    si, es:RTC2
  101.         loope    TimeRTC
  102.  
  103.         pop    si
  104.         pop    dx
  105.         pop    cx
  106.         pop    bx
  107.         pop    ax
  108.         pop    es
  109.         pop    ds
  110.         ret
  111. Delay18        endp
  112.  
  113.  
  114.  
  115. ; DelayInit-    Computes the timing constant for the Delay18 routine
  116. ;        by watching when the RTC code updates the RTC variable.
  117.  
  118. DelayInit    proc
  119.         push    es
  120.         push    ax
  121.         push    bx
  122.         push    cx
  123.         push    dx
  124.         push    si
  125.  
  126.         mov    ax, 40h
  127.         mov    es, ax
  128.         mov    ax, RTC
  129. RTCMustChange:    cmp    ax, RTC
  130.         je    RTCMustChange
  131.  
  132.         mov    cx, 0
  133.         mov    si, RTC
  134.         mov    dx, PPI_B
  135.         align    4
  136. TimeRTC:    mov    bx, 50
  137.         align    4
  138. DelayLp:    dec    bx
  139.         jne    DelayLp
  140.         cmp    si, RTC
  141.         loope    TimeRTC
  142.  
  143.         neg    cx            ;CX counted down!
  144.         shl    cx, 1            ;Increase delay time.
  145.         mov    TimedValue, cx        ;Save away
  146.  
  147.         pop    si
  148.         pop    dx
  149.         pop    cx
  150.         pop    bx
  151.         pop    ax
  152.         pop    es
  153.         ret
  154. DelayInit    endp
  155.  
  156.  
  157.  
  158.  
  159.  
  160. ; PlayNote-    This procedure programs the 8254 timer chip to play a given
  161. ;        note (frequency is passed in AX) for a given duration (passed
  162. ;        in cx).
  163.  
  164. PlayNote    proc
  165.         push    dx
  166.         push    cx
  167.         push    ax
  168.  
  169. ; Turn on the speaker.
  170.  
  171.         in    al, PPI_B
  172.         or    al, 3
  173.         out    PPI_B, al
  174.  
  175. ; Tell the chip we want to program it with a new 16-bit divisor value.
  176.  
  177.         mov    al, 0B6h    ;Magic value to program chip.
  178.         out    PIT_CW, al
  179.  
  180. ; Convert the frequency to a divisor constant.
  181.  
  182.         pop    cx        ;Get the frequency.
  183.  
  184.         mov    dx, word ptr DivisorConst+2
  185.         mov    ax, word ptr DivisorConst
  186.         div    cx
  187.  
  188.         out    PIT_Ch2, al
  189.         xchg    al, ah
  190.         out    PIT_Ch2, al
  191.  
  192.         mov    ax, cx        ;Restore original AX value.
  193.         pop    cx        ;Retrieve duration
  194.         mov    dx, cx        ;Save Duration.
  195. DelayLp:    call    Delay18
  196.         loop    DelayLp
  197.         mov    cx, dx        ;Restore original CX value
  198.  
  199.         pop    dx        ;Restore original DX value.
  200.         ret
  201. PlayNote    endp
  202.  
  203.  
  204. ; Main program which tests out the DELAY subroutine.
  205.  
  206. Main        proc
  207.         mov    ax, dseg
  208.         mov    ds, ax
  209.         mov    es, ax
  210.  
  211.         call    DelayInit
  212.  
  213. ; Play "Amazing Grace"
  214.  
  215.         note    294, 4
  216.         note    392, 8
  217.         note    494, 2
  218.         note    392, 2
  219.         note    494, 8
  220.         note    440, 4
  221.         note    392, 8
  222.         note    330, 4
  223.         note    294, 8
  224.         rest    2
  225.         note    294, 4
  226.         note    392, 8
  227.         note    494, 2
  228.         note    392, 2
  229.         note    494, 8
  230.         note    440, 4
  231.         note    587, 16
  232.  
  233.         note    494, 4
  234.         note    587, 4
  235.         note    494, 2
  236.         note    587, 2
  237.         note    494, 2
  238.         note    392, 8
  239.         note    294, 4
  240.         note    330, 4
  241.         note    392, 2
  242.         rest    2
  243.         note    392, 2
  244.         note    330, 2
  245.         note    294, 8
  246.         rest    2
  247.         note    294, 4
  248.         note     392, 8
  249.         note    494, 2
  250.         note    392, 2
  251.         note    494, 8
  252.         note    440, 4
  253.         note    392, 16
  254.  
  255.  
  256.         rest    1
  257.  
  258.  
  259.  
  260. Quit:        ExitPgm            ;DOS macro to quit program.
  261. Main        endp
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269. cseg            ends
  270.  
  271.  
  272.  
  273. sseg        segment    para stack 'stack'
  274. stk        dw    1024 dup (0)
  275. sseg        ends
  276.         end    Main
  277.